import React, { useContext, useReducer, useState, useEffect, useCallback } from 'react';
import { ethers, providers } from 'ethers'
import style from './index.module.less';
import ContractUtil from '@/utils/ContractUtil';
import Images from '@/image'
import WhiteHeightSpace from '@/components/WhiteSpace/WhiteHeightSpace';
import { debounce, inputFormatNumber } from '@/utils/utils';
import BigNumber from 'bignumber.js';
import { isLessEqualTo } from '@/utils/bigNumber';
import { useDebounce } from '@/hooks/useDebounce';
const mainContractAbi = require('../../../contract/abi/mainContract.json')
const gdchentTokenAbi = require('../../../contract/abi/gdchentTokenAbi.json')
const mainAddress = '0x81147759ADEd8630A825ea808A63AC9a81CDc0c8'
const GdchentTokenAddress = '0x593af9706EC851747A8A87cea30d266341d5262e'
const MAX_COUNT = 10
interface IProps { }
const HomeContent = (props: IProps) => {
    const [inputTokenCode, setInputTokenCode] = useState<string>('')
    const [inputNumber, setInputNumber] = useState<number>(1)
    const [mainBalance, setMainBalance] = useState<string>('0')
    const [account, setAccount] = useState<string>('')
    const [toAddress, setToAddress] = useState('0x76A6e784BcD6676093C40F2ae068CDBF7073dD92');
    const [sendMsgMoney, setSendMsgMoney] = useState('1');

    //通过钱包私钥获取钱包地址
    const getAccountAddressByPrivate = useCallback(() => {
        if ((window as any)) {
            try {
                const privateKey = "e714d873c046aa25df761d7f0f263caa2d4594778c8174e075bfeb26a9b968f1"
                const address = ContractUtil.getAccountAddressByPrivate(privateKey)
                console.log("通过私钥得到钱包地址", address)
            } catch (e) {
                console.log("e", e)
            }
        }
    }, [])

    //通过合约来查询原生币种的余额
    const getBalanceByContranct = useCallback(async () => {
        //拿到provider 
        if ((window as any)) {
            try {
                const provider = ContractUtil.getProvider()
                // 发送者地址
                if (!!provider) {
                    const signer = provider.getSigner()
                    console.log("sign", signer)
                    const network = await provider.getNetwork()
                    console.log("获取网络", network)
                    //连接钱包
                    const accountArr: string[] = await provider.send("eth_requestAccounts", []);
                    console.log("获取钱包地址", accountArr, signer)
                    const account = accountArr[0]
                    console.log("动态获取当前钱包连接的账号", account)
                    const balance: ethers.BigNumber = await provider.getBalance(account);
                    const balanceStr = ethers.utils.formatEther(balance)
                    console.log("查询余额", balanceStr)
                    const blockNumber = await provider.getBlockNumber()
                    console.log("获取区块号", blockNumber)
                    const gasPriceAsGwei = await provider.getGasPrice().then((res) => {
                        return ethers.utils.formatUnits(res, 'gwei');
                    });
                    console.log("gas价格gasPrice", gasPriceAsGwei)
                    // https://www.cnblogs.com/x-poior/p/10511583.html
                    provider.on("BatchMintWithEther", (result) => {
                        console.log("监听BatchMintWithEther结果", result)
                    })
                    const mainContract = ContractUtil.getContract(mainAddress, mainContractAbi, false)
                    console.log("contract", mainContract)
                    const mainBalanceBig: ethers.BigNumber = await mainContract?.getMainTokenBalance()
                    const mainBalance = ethers.utils.formatEther(mainBalanceBig)
                    console.log("合约方式查询主币种余额", mainBalance)
                }
            } catch (e) {
                console.log("exception", e)
            }
        }
    }, [ethers])

    /**
     * 动态通过当前钱包获取连接钱包的地址余额
     */
    const getBalanceByWallet = useCallback(async () => {
        //拿到provider 
        if ((window as any)) {
            try {
                const provider = ContractUtil.getProvider()
                // 发送者地址
                if (!!provider) {
                    const network = await provider.getNetwork()
                    console.log("获取网络", network)
                    //连接钱包
                    const accountArr: string[] = await provider.send("eth_requestAccounts", []);
                    console.log("获取钱包地址", accountArr)
                    if (accountArr && Array.isArray(accountArr)) {
                        const account = accountArr[0]
                        console.log('account', account)
                        console.log("动态获取当前钱包连接的账号", account)
                        const balance: ethers.BigNumber = await provider.getBalance(account);
                        const balanceStr = ethers.utils.formatEther(balance)
                        console.log("钱包方式查询余额", balanceStr)
                        setMainBalance(balanceStr)
                        setAccount(account)
                    }
                }
            } catch (e) {
                console.log("exception", e)
            }
        }
    }, [])
    //发送主币种给B用户
    const sendMainEther = useCallback(async () => {
        //拿到provider 
        if ((window as any)) {
            try {
                const provider = ContractUtil.getProvider()
                if (provider) {
                    // 发送者地址
                    const signer = provider.getSigner()
                    console.log("provider", provider)
                    console.log("sign", signer)
                    const network = await provider.getNetwork()
                    console.log("获取网络", network)
                    //连接钱包
                    const accountArr: string[] = await provider.send("eth_requestAccounts", []);
                    console.log("获取钱包地址", accountArr, signer)
                    const account = await signer.getAddress();
                    console.log("动态获取当前钱包连接的账号", account)
                    const balance: ethers.BigNumber = await provider.getBalance(account);
                    const balanceStr = ethers.utils.formatEther(balance)
                    console.log("查询余额", balanceStr)
                    const blockNumber = await provider.getBlockNumber()
                    console.log("获取区块号", blockNumber)
                    const gasPriceAsGwei = await provider.getGasPrice().then((res) => {
                        return ethers.utils.formatUnits(res, 'gwei');
                    });
                    console.log("gasPrice", gasPriceAsGwei)
                    // https://www.cnblogs.com/x-poior/p/10511583.html

                    const mainContract = ContractUtil.getContract(mainAddress, mainContractAbi, false)
                    mainContract.on("SendMainEther", (_addr, totalBig, currentBig) => {
                        console.log("监听SendMainEther结果", _addr, ethers.utils.formatEther(totalBig), ethers.utils.formatEther(currentBig))
                    })
                    const mainBalanceBig: ethers.BigNumber = await mainContract?.getMainTokenBalance()
                    const mainBalance = ethers.utils.formatEther(mainBalanceBig)
                    console.log("主币种余额2", sendMsgMoney)
                    const result = await mainContract?.sendMainEther(toAddress, 1, {
                        value: ethers.utils.parseEther(sendMsgMoney)
                    })
                    console.log("result", result)
                    if (result && result.hash) {
                        const transactionResult = await mainContract.provider.waitForTransaction(result.hash)
                        console.log("获取交易状态", transactionResult)
                        getBalanceByWallet()
                    }
                }
            } catch (e) {
                console.log("exception", e)
            }
        }
    }, [ethers, sendMsgMoney])

    //发送主币种给B用户
    const sendErc20Ether = useCallback(async () => {
        //拿到provider 
        if ((window as any)) {
            try {
                const provider = ContractUtil.getProvider()
                if (provider) {
                    // 发送者地址
                    const signer = provider.getSigner()
                    console.log("provider", provider)
                    console.log("sign", signer)
                    const network = await provider.getNetwork()
                    console.log("获取网络", network)
                    //连接钱包
                    const accountArr: string[] = await provider.send("eth_requestAccounts", []);
                    console.log("获取钱包地址", accountArr)
                    if (accountArr && Array.isArray(accountArr)) {
                        const account = accountArr[0]
                        console.log('account', account)
                        console.log("动态获取当前钱包连接的账号", account)
                        //const account = await signer.getAddress();
                        const balance: ethers.BigNumber = await provider.getBalance(account);
                        const balanceStr = ethers.utils.formatEther(balance)
                        console.log("查询余额", balanceStr)
                        const blockNumber = await provider.getBlockNumber()
                        console.log("获取区块号", blockNumber)
                        const gasPriceAsGwei = await provider.getGasPrice().then((res) => {
                            return ethers.utils.formatUnits(res, 'gwei');
                        });
                        console.log("gasPrice", gasPriceAsGwei)
                        // https://www.cnblogs.com/x-poior/p/10511583.html

                        const erc20Contract = ContractUtil.getContract(GdchentTokenAddress, gdchentTokenAbi, false)
                        console.log("erc20Contract", erc20Contract)
                        const resultBig: ethers.BigNumber = await erc20Contract?.balanceOf(account)
                        const erc20Balance1 = ethers.utils.formatEther(resultBig)
                        console.log("余额1", erc20Balance1)
                        //使用transfer直接转账
                        const res = await erc20Contract?.transfer(
                            toAddress,
                            String(50 * 10 ** 18)
                        )
                        if (!!res && !!res.hash) {
                            const transactionResult = await erc20Contract?.signer.provider?.waitForTransaction(res.hash)
                            console.log("转账交易结果", transactionResult)
                            if (transactionResult?.status === 1) {
                                const erc20BalanceBig: ethers.BigNumber = await erc20Contract?.balanceOf(account)
                                const erc20Balance2 = ethers.utils.formatEther(erc20BalanceBig)
                                console.log("erc20币种余额", erc20Balance2)
                            }
                        }
                    }
                }
            } catch (e) {
                console.log("exception", e)
            }
        }
    }, [ethers, sendMsgMoney, toAddress])

    //-1
    const subtractOnclick = useCallback(() => {
        if (inputNumber <= 1) {
            return
        }
        const newInputNumber = inputNumber - 1;
        setInputNumber(newInputNumber)
    }, [inputNumber])

    const addOnclick = useCallback(() => {
        if (inputNumber >= MAX_COUNT) {
            return
        }
        const newInputNumber = inputNumber + 1;
        setInputNumber(newInputNumber)
    }, [inputNumber])
    //获取钱包余额通过合约方式来获取原生币种的余额
    const getBalanceByContranctClick = useDebounce(getBalanceByContranct, 2000)
    const getBalanceByWalletClick = useDebounce(getBalanceByWallet, 2000)
    const sendMainEtherClick = useDebounce(sendMainEther, 2000)
    const sendErc20EtherClick = useDebounce(sendErc20Ether, 2000)
    return (
        <div className={style.container}>
            <div className={style.content}>
                <WhiteHeightSpace height={'50px'} />
                {/* 查询余额  */}
                <div className={style.buttonText} onClick={() => {
                    getBalanceByWalletClick()
                }}>钱包方式查询主币种余额</div>
                <WhiteHeightSpace height={'20px'} />
                <div className={style.buttonText} onClick={() => {
                    getBalanceByContranctClick()
                }}>合约方式查询主币种余额</div>
                <WhiteHeightSpace height={'10px'} />
                <div className={style.mainBalance}>当前钱包{account ? account : ''}主币种余额 : {mainBalance}</div>
                <WhiteHeightSpace height={'20px'} />
                <div className={style.inputNodeLine}>
                    <input className={style.inputInviteCode} value={inputTokenCode} onChange={(e) => {
                        setInputTokenCode(e.target.value.trim())
                    }} />
                    <div className={style.inputRelative}>
                        <input
                            type={'number'}
                            className={style.inputNumber}
                            value={inputNumber ? inputNumber : ''}
                            onChange={(e) => {
                                const inputNumber = parseInt(e.target.value.trim())
                                const inputNum = inputNumber > MAX_COUNT ? 1 : inputNumber
                                setInputNumber(inputNum)
                            }}
                        />
                        <img src={Images.inputSubtract} className={style.inputIconSub} onClick={() => {
                            subtractOnclick()
                        }} />
                        <img src={Images.inputAdd} className={style.inputIconAdd}
                            onClick={() => {
                                addOnclick()
                            }}
                        />
                    </div>
                </div>
                <WhiteHeightSpace height={'20px'} />
                <div className={style.inputLine}>
                    <input
                        className={style.inputAddress}
                        placeholder={'请输入地址'} value={toAddress} onChange={(e) => {
                            setToAddress(e.target.value)
                        }} />
                    <input
                        type={'number'}
                        className={style.inputMoney}
                        placeholder={'请输入转账金额'} value={sendMsgMoney} onChange={(e) => {
                            console.log("e", e.target.value)
                            const val = !!e.target.value ? e.target.value : '0'
                            let inputNumber = inputFormatNumber(val, 3)
                            if (isLessEqualTo(inputNumber, 0)) {
                                inputNumber = ''
                            }
                            if (Number.isNaN(inputNumber)) {
                                inputNumber = ''
                            }
                            setSendMsgMoney(inputNumber)
                        }} />
                </div>

                <WhiteHeightSpace height={'20px'} />
                <div className={style.buttonText} onClick={() => {
                    sendMainEtherClick()
                }}>发送主币种给B用户</div>
                <WhiteHeightSpace height={'20px'} />
                <div className={style.buttonText} onClick={() => {
                    sendErc20EtherClick()
                }}>发送erc20币种给B用户</div>
                <WhiteHeightSpace height={'20px'} />
                <div className={style.buttonText} onClick={() => {
                    getAccountAddressByPrivate()
                }}>通过私钥获取钱包地址</div>
            </div>
        </div>
    )
}
export default HomeContent;
